package org.smile.util;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * 数字操作工具类
 * 
 * @author strive
 * 
 */
public class NumberUtils {
	/**
	 * 82进制
	 */
	private static final char CHAR[] = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g',
			'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
			'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
			'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
			'X', 'Y', 'Z', '=', '*', '_', '~', '@', '#', '-', '(', ')', ',',
			'.', '/', '?', ':', ';', '<', '>', '$', '%', '+', '^', '&'};
	// 字符与10进制数字的对应表
	private static final Map<Character, Integer> CHAR_MAP;
	static {
		CHAR_MAP = new HashMap<Character, Integer>();
		for (int i = 0; i < CHAR.length; i++) {
			CHAR_MAP.put(CHAR[i], i);
		}
	}

	/**
	 * 转换十进制为其它进制字符串
	 * 
	 * @param i
	 * @param radix
	 * @return
	 */
	public static String toString(long i, int radix) {
		if (radix < Character.MIN_RADIX || radix > CHAR.length) {
			radix = 10;
		}
		if (radix == 10)
			return String.valueOf(i);
		char[] buf = new char[65];
		int charPos = 64;
		boolean negative = (i < 0);

		if (!negative) {
			i = -i;
		}

		while (i <= -radix) {
			buf[charPos--] = CHAR[(int) (-(i % radix))];
			i = i / radix;
		}
		buf[charPos] = CHAR[(int) (-i)];

		if (negative) {
			buf[--charPos] = '-';
		}
		return new String(buf, charPos, (65 - charPos));
	}

	/**
	 * 数字格式化
	 * 
	 * @param number
	 * @param formatText
	 * @return
	 */
	public static String format(Number number, String formatText) {
		DecimalFormat df = new DecimalFormat(formatText);
		return df.format(number);
	}

	/**
	 * 字符串解析成Long
	 * 
	 * @param number
	 * @param radix
	 * @return
	 */
	public static Long parseLong(String number, int radix) {
		if(number.charAt(0)=='-'){
			return -parseLong(number.substring(1,number.length()),radix);
		}
		if (radix > CHAR.length) {
			throw new RuntimeException(new StringBuffer("指定的进制").append(radix)
					.append("太大不支持解析").toString());
		}
		long result = 0;
		char[] numberChar = number.toCharArray();
		char currentChar;
		int bit;
		int len = numberChar.length;
		for (int i = len - 1; i >= 0; i--) {
			currentChar = numberChar[len - i - 1];
			bit = CHAR_MAP.get(currentChar);
			if (bit > radix) {
				throw new RuntimeException(new StringBuffer("解析数字出错:字符 ")
						.append(currentChar).append(" 代表数字").append(bit)
						.append("大于进制值").append(radix).toString());
			}
			result += bit * Math.pow((double) radix, i);
		}
		return result;
	}
}
